# import util.des as des
######下面的代码进行重新加载模块##########
import datetime
import inspect
import json
import os
import re
import sys
import traceback
from importlib import reload

import requests

import config
# coding=utf-8
# 文件：inter.py
# import database as db
# import mq
import pub
import settings
# import util.module_util

#当前目录名称
CURRENT_DIR_PATH = os.path.dirname(inspect.currentframe().f_code.co_filename)
sys.path.append(CURRENT_DIR_PATH + "/..")

# reload(util.module_util)
# util.module_util.reload_modules()

RESULT_QUEUE_NAME       = 'fv.result'
QUEUE_NAME_DELAY_ADAY   = 'fv.result.delay.1day'
QUEUE_ADAY_DELAY_TIME   = 24 * 60 * 60 * 1000


# 家人专用的类,用于变量申明
class myObject(object):
    '''家人专用的类,用于变量申明'''
    pass


# 定义基础类
class base_class():
    """ 定义基础类 """
    logger = settings.get_log("base")

    def __init__(self, id, extra, steps):
        self.is_test = None
        self.app = self.pipe.sel_info_one()

        self.app.update({
            "application_id": "EGOKMCZQGQ",
            "application_status": 1,
            "visit_reason": "3",
            "lang_visit_reason_where": ""
        })
        #查询签证资料
        # sql = 'select * from qdgcms_app left outer join qdgcms_app_lang on qdgcms_app.id=qdgcms_app_lang.app_id where id=' + str(id)
        # app         = db.get_one(sql)   # 查询签证主信息表
        #print app
        # self.app_lang = db.get_one("select * from " + config.DB_PREFIX + "app_lang where app_id=" + str(id))    #查询签证语言信息表
        #print self.app_lang
        #查询家庭成员表
        # self.family_list = db.get_list("select * from " + config.DB_PREFIX + "app_family f inner join " + config.DB_PREFIX +
        # "app_family_lang l on f.id=l.family_id where f.app_id=%s and l.country_id=%s",(id,app["country_id"]))

        #print "select * from " + config.DB_PREFIX + "app_family f inner join " +
        # config.DB_PREFIX + "app_family_lang l on f.id=l.family_id where f.app_id=680"

        #查询附加信息表
        # self.extra_list = db.get_list("select * from " + config.DB_PREFIX + "app_extra f left outer join " + config.DB_PREFIX +
        #  "app_extra_lang l on f.id=l.extra_id where f.app_id=%s and l.country_id=%s",(id,app["country_id"]))

        #数据解密
        # app['chinese_name'] = des.my_decrypt(app['chinese_name'])
        # app['id_number'] = des.my_decrypt(app['id_number'])
        # app['tel'] = des.my_decrypt(app['tel'])
        # app['mobile'] = des.my_decrypt(app['mobile'])
        # app['surnames'] = des.my_decrypt(app['surnames'])
        # app['given_names'] = des.my_decrypt(app['given_names'])
        #签证附加信息
        # if app["moreinfo"]:
        #     try:
        #         app["moreinfo"]    = json.loads(app["moreinfo"])
        #     except:
        #         app["moreinfo"]    = { }
        # else:
        #     app["moreinfo"]    = { }
        # self.app        = app
        self.extra      = extra
        self.steps      = steps
        #pub.log(id,'查询到的APP',str(self.app))
        #app id
        self.app_id     = id
        # self.passport   = app['passport_number']
        #获取team信息
        # if(app['team_id'] > 0):
        #     team = db.get_one("select * from " + config.DB_PREFIX + "team where id=%s", [app['team_id']])
        #     self.app["visa_type"]           = team["visa_type"]
        #     self.app["arrival_time"]       = team["arrival_time"]
        #     self.app["departure_time"]    = team["departure_time"]
        #     self.team   = team
        #     if self.team["ext"]:
        #         try:
        #             self.team["ext"]    = json.loads(self.team["ext"])
        #             if not self.app["moreinfo"]:
        #                 self.app["moreinfo"] = { }
        #             for (k,v) in  self.team["ext"].items():
        #                 self.app["moreinfo"][k] = v
        #         except:
        #             self.team["ext"]    = { }
        #     self.team['extra_list'] = db.get_list("select * from " + config.DB_PREFIX + "app_extra f left outer join " + config.DB_PREFIX + "app_extra_lang l on f.id=l.extra_id where f.team_id=%s",(app['team_id']))
        # else:
        #     self.team = None

        #读取文件已经上传的文件列表 add by sunjie 20181017
        # self.material_list = db.get_list("select mu.*,bm.material_type,bm.e_name from " + config.DB_PREFIX + "material_up mu inner join " + config.DB_PREFIX + "base_material bm on mu.material_id = bm.id  where mu.status = '2' and mu.app_id=" + str(id) + " order by bm.material_type")
        #待上传文件本地存放根目录,各个国家可以在此基础上加上国家编码的下级文件夹  例如：E:\\visafile\\260\\
        self.local_path = 'E:\\visafile'
        #开启会话
        self.requests = requests.Session()
        self.requests.verify = False
        self.requests.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0',
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3'
        }
        self.requests.timeout = 60    # 超时时间:1分钟
    pass

    def get_bank_info(self):
        try:
            now_url = config.BASE_BANK_CARD_INFO_URL
            pub.log(self.app_id, "获取付款账号请求地址:", now_url)
            req = self.get(now_url)
            res = req.text.encode('utf8')
            pub.log(self.app_id, "获取付款账号请求结果:", res)
            data = json.loads(res)
            # key = data['salt']
            #信用卡有效期-账号
            self.pay_account_no = data['account']
            #信用卡有效期-姓名
            self.pay_account_name = data['accountName']
            timestamp = data['validDate']
            timestamp = timestamp / 1000
            tmp_date = datetime.datetime.utcfromtimestamp(timestamp)
            #信用卡有效期-月
            self.pay_account_month = tmp_date.strftime('%m')
            #信用卡有效期-年
            self.pay_account_year = tmp_date.strftime('%Y')
            #信用卡有效期-cvv码
            self.pay_account_cvv = data['cvv']
            return True
        except Exception as e:
            self.logger.debug('str(Exception):\t%s' % str(Exception))
            self.logger.debug('str(e):\t\t%s' % str(e))
            self.logger.debug('repr(e):\t%s' % repr(e))
            self.logger.debug('e.message:\t%s' % e.message if hasattr(e, "message") else str(e))
            self.logger.debug('traceback.print_exc(): %s' % traceback.print_exc())
            self.logger.debug('traceback.format_exc():\n%s' % traceback.format_exc())
            self.logger.debug("%s 获取付款账号失败!!! %s" % (self.app_id, traceback.format_exc()))
            return False
    pass

    #保存大使馆订单号
    def save_thOrderNo(self):
        sql = "update qdgcms_app set application_id = %s where id = %s"
        db.update(sql,(self.third_order_no,self.app_id))
    pass

    #保存大使馆已经进行的步骤
    def save_thStatus(self,status):
        sql = "update qdgcms_app set application_status = %s where id = %s"
        db.update(sql,(status,self.app_id))
    pass

    #get 请求
    def get(self, url, try_count=0, **kwargs):
        try:
            return self.requests.get(url,**kwargs)
        except Exception as exc:
            pub.log(self.app_id, "网络异常", url + "; 异常信息:" + traceback.format_exc())
            if(try_count < 5):
                return self.get(url,try_count=try_count+1, **kwargs)
            else:
                raise exc
    #post 请求
    def post(self,url, data=None, try_count=0, **kwargs):
        try:
            #将所有的值转化为大写
            if data and isinstance(data, dict):
                keys = data.keys()
                for j in range(0, len(keys)):
                    #若为None则设置为空字符串
                    if data[keys[j]] is None:
                        data[keys[j]] = ""
            return self.requests.post(url, data=data, **kwargs)
        except Exception as exc:
            pub.log(self.app_id, "网络异常", traceback.format_exc())
            if(try_count < 5):
                return self.post(url, data=data,try_count=try_count+1, **kwargs)
            else:
                raise exc
    #查询签证结果
    def result_queue(self,delay_days = 1):
        mq.send_delay_message(QUEUE_NAME_DELAY_ADAY, '{"id":' + str(self.app_id) + '}',QUEUE_ADAY_DELAY_TIME, RESULT_QUEUE_NAME)
    #更新当前填写表格的步骤
    def update_app_step(self,steps,note=''):
        sql = "update " + config.DB_PREFIX + "app set steps=%s,note=%s where id=%s"
        params = (steps,note,self.app_id)
        db.update(sql,params)
    #更新当前填写表格的备注
    def update_app_note(self,note):
        sql = "update " + config.DB_PREFIX + "app set note=%s where id=%s"
        params = (note,self.app_id)
        db.update(sql,params)
    #根据Id获取基础选项（base_option）的code
    def get_base_option_code(self,option_id):
        if(option_id is None): return ""
        opt = db.get_one("select code from " + config.DB_PREFIX + "base_option where id=" + str(option_id))
        if(opt is not None):
            return opt['code']
        else:
            return ""
    #根据Id获取基础选项（base_option）的code2
    def get_base_option_code2(self,option_id):
        if(option_id is None): return ""
        opt = db.get_one("select code2 from " + config.DB_PREFIX + "base_option where id=" + str(option_id))
        if(opt is not None):
            return opt['code2']
        else:
            return ""
    #获取国家编码
    def get_base_country_code(self,id, country):
        if(id is None or country is None): return ""
        field = "code_" + str(country)
        opt = db.get_one("select " + field + " from " + config.DB_PREFIX + "base_country where id=" + str(id))
        if(opt is not None):
            return opt[field]
        else:
            return ""
    #获取国家英文名称
    def get_base_country_english_name(self,id):
        return pub.get_field_value("base_country", "english_name", {"id": id})
    #获取省或州的编码
    def get_base_province_code(self,id):
        if(id is None): return ""
        opt = db.get_one("select code from " + config.DB_PREFIX + "base_province where id=" + str(id))
        if(opt is not None):
            return opt['code']
        else:
            return ""
    #获取洲的英文名
    def get_base_province_name_en(self,province_id):
        return pub.get_province_name_en(province_id)
    #获取城市英文名称
    def get_base_city_name_en(self,city_id):
        return pub.get_city_name_en(city_id)
    #获取语言英文
    def get_base_language_en(self,id):
        return pub.get_language_en(id)
    #写日志
    def log(self,msg):
        self.logger.info(msg)
    #根据附加信息类型获取附加信息(单个)
    def get_extra_by_type(self,type):
        for i in range(0, len(self.extra_list)):
            if(self.extra_list[i]['extra_type'] == type):
                return self.extra_list[i]
        return None
    #根据家庭成员类型获取家庭成员(单个)
    def get_family_by_type(self,type):
        for i in range(0, len(self.family_list)):
            if(self.family_list[i]['type'] == type):
                return self.family_list[i]
        return None
    #获取国家编码
    def get_base_visa_type(self,id):
        if(id is None): return None
        opt = db.get_one("select name_en,code,code2 from " + config.DB_PREFIX + "base_visa_type where id=" + str(id))
        if(opt is not None):
            return opt
        else:
            return None
    #根据附加信息类型获取附加信息列表
    def get_extra_list_by_type(self,type):
        lst = []
        for i in range(0, len(self.extra_list)):
            if(self.extra_list[i]['extra_type'] == type):
                lst.append(self.extra_list[i])
        return lst
    #地址切分函数
    def get_addr_sp(self,addr, type,maxlen):
        addr = addr.replace(', ',',')
        pos = maxlen - 1
        is_line2 = False
        is_sp = True
        if(len(addr) > maxlen):
            is_line2 = True
            i = addr.rfind(',', 0, pos)
            if(len(addr[i+1:80]) <= maxlen):
                pos = i
                if(type == 2): pos = i + 1
                is_sp = False
            else:
                strtmp = addr[pos:pos+2]
                if(pub.get_reg_value(r'[a-zA-Z\d]{2}',strtmp) == ""):
                    pos = pos + 1
                    is_sp = False
        #获取第一行
        if(type == 1):
            if(is_line2 == True):
                ret = addr[0:pos]
                if(is_sp == True): ret = ret + '-'
                return ret.strip()
            else:
                return addr[0:maxlen].strip()
        else:
            if(is_line2 == True):
                return addr[pos:100].strip()
            else:
                return ""
    #获取地址的第一行
    def get_addr_line1(self,addr,maxlen):
        ret = self.get_addr_sp(addr, 1,maxlen).strip()
        result, number = re.subn(r'^[,\.]+', '', ret)
        return result
    #获取地址的第二行
    def get_addr_line2(self,addr,maxlen):
        ret = self.get_addr_sp(addr, 2,maxlen).strip()
        result, number = re.subn(r'^[,\.]+', '', ret)
        return result
    #自动换行
    def str_auto_line(self, str, maxlen, linchar="<br/>"):
        return self.get_addr_line1(str,maxlen) + linchar + self.get_addr_line2(str,maxlen)
    #自动将英文字符串分割为多行，返回列表
    def str_split_line(self,addr,maxlen):
        orimaxlen = maxlen  #将原来的最大长度存储
        lines = []      #返回的集合对象
        addr = addr.replace(', ',',')
        #print addr
        pos = 0 #当前位置
        tmpstr = ""
        max_add_one = False
        small_char_flag = 0     #占宽度较小的标记，若累计两个小字符，则该行最大长度增加1
        while pos < len(addr):
            #如果是新航，则不要标点符号
            if(not tmpstr and addr[pos] in [' ',',','.','-']):
                pass
            else:
                tmpstr += addr[pos]
                #占宽度较小的标记，若累计两个小字符，则该行最大长度增加1
                if addr[pos] in ['.',' ',',','I']:
                    #print "*" + addr[pos]
                    small_char_flag=small_char_flag+1
                    if small_char_flag == 2:
                        maxlen = maxlen + 1
                        small_char_flag = 0
                if(len(tmpstr) == maxlen-1):
                    #若当前字符不是符号，则加一个换行符号，否则开启新的行
                    if(addr[pos] not in [' ',',','.','-']):
                        if(pos+1 < len(addr)):
                            if(pub.get_reg_value(r'[a-zA-Z0-9]',addr[pos+1])):
                                tmpstr += "-"
                    else:
                        lines.append(tmpstr)
                        tmpstr = ""
                        continue
            #若字符串中的长度超出最大长度，则开始新的字符串
            if(len(tmpstr) >= maxlen):
                #print "======" + str(maxlen)
                lines.append(tmpstr)
                tmpstr = ""
                maxlen = orimaxlen  #恢复最大长度为初始值
            pos = pos + 1
        if(tmpstr):
            lines.append(tmpstr)
        return lines
    #获取第一行
    def get_str_line1(self,addr,maxlen):
        strs = self.str_split_line(addr, maxlen)
        if len(strs) > 0: return strs[0]
        else: return ""
    #获取第二行
    def get_str_line2(self,addr,maxlen):
        strs = self.str_split_line(addr, maxlen)
        if len(strs) > 1: return strs[1]
        else: return ""
    #获取第三行
    def get_str_line3(self,addr,maxlen):
        strs = self.str_split_line(addr, maxlen)
        if len(strs) > 2: return strs[2]
        else: return ""
    #获取第四行
    def get_str_line4(self,addr,maxlen):
        strs = self.str_split_line(addr, maxlen)
        if len(strs) > 3: return strs[3]
        else: return ""
    def str_auto_line_str(self, str, maxlen, linchar="<br/>"):
        res = self.str_split_line(str,maxlen)
        str = ""
        for i in range(0,len(res)):
            if(i > 0):
                str += linchar
            str += res[i]
        return str
    #构造英文地址
    def make_addr_en(self,province, city ,addr, country = ""):
        if not province: province = ""
        if not city: city = ""
        if city.capitalize() not in addr: addr += "," + city.capitalize()
        if province.capitalize() not in addr: addr += "," + province.capitalize()
        if country: addr += "," + country.capitalize()
        return addr.upper()
    #构造英文地址[不转大写]
    def make_addr_en2(self,province, city ,addr, country = "", district=""):
        if not province: province = ""
        if not city: city = ""
        if not district: district = ""
        if district.capitalize() not in addr: addr += "," + district.capitalize()
        if city.capitalize() not in addr: addr += "," + city.capitalize()
        if province.capitalize() not in addr: addr += "," + province.capitalize()
        if country: addr += "," + country.capitalize()
        return addr
    #构造英文地址
    def make_addr_cn(self,province, city ,addr, country = "", district=""):
        if district not in addr: addr = district + addr
        if city not in addr: addr = city + addr
        if province not in addr: addr = province + addr
        if country: addr = country + addr
        return addr
    #获取代理人信息
    def get_preparer(self):
        #查询旅行社信息
        agent = db.get_one("select * from " + config.DB_PREFIX + 'agent where id=%s',(self.app['agent_id']))
        #获取旅行社设置的代填表人信息
        if agent:
            preparer = db.get_one('select * from ' + config.DB_PREFIX + 'abroad_contact where contact_type=1 and country=100 and (agent_id=%s or (parter_id=0 and agent_id=0) or (agent_id=0 and parter_id=%s)) order by agent_id desc,parter_id desc limit 1',(self.app['agent_id'],agent['parter_id']))
        else:
            preparer = db.get_one('select * from ' + config.DB_PREFIX + 'abroad_contact where contact_type=1 and country=100 and agent_id=0 and (parter_id=0 or parter_id=%s) order by parter_id desc limit 1',(self.app['parter_id']))
        return preparer
    #签证状态自动设置为成功
    def set_app_success(self):
        db.save("app", {"status": 1, "process_status": 4}, "id=%s", [self.app_id])
        #查询是否还有未处理完的签证，如果没有，则修改主订单的状态为待邮寄
        exists = db.get_one("select id from qdgcms_app where order_id=%s and status<>1", [self.app["order_id"]])
        if not exists:
            order   = db.get_one("select id,product_id,work_flow,inner_status from qdgcms_order where id=%s", [self.app["order_id"]])
            product = db.get_one("select is_only_form,is_delivery_material from qdgcms_product where id=%s",[order["product_id"]])
            data = { }
            if product["is_only_form"]:
                data["order_status"]    = 8
            else:
                if product["is_delivery_material"] and order["inner_status"] == 0:
                    data["order_status"]    = 9     #处理完成待邮寄护照
                    data["inner_status"]    = 1     #内部状态改为待交材料
                else:
                    data["order_status"]    = 8
            data["work_flow"]   = pub.make_app_work_flow("资料处理完成", "", "系统")
            self.logger.info(data)
            db.save("order", data, "id=%s", [order["id"]])
    def run(self):
        pub.log(self.app_id,"异常信息","接口未实现")
        pass
